<template>
  <!-- 单选图库图片 -->
  <div
    v-if="pictureList.length > 0"
    v-for="item in pictureList"
    :key="item.pictureId"
    class="border-2px border-dashed border-[--el-color-primary] hover:bg-[--el-color-primary-light-9] m-r-2px m-t-2px"
    :style="{ width: props.width, height: props.height, 'border-radius': props.rounded }"
  >
    <div v-if="pictureList.length > 0" class="koi-pictures-box">
      <img :src="item.picturePath" class="koi-picture" :style="{ 'border-radius': props.rounded }" />
      <div class="koi-picture-operate" @click.stop>
        <div v-if="!props.disabled" class="koi-picture-icon" @click="handleEditPicture">
          <el-icon><Edit /></el-icon>
          <span>编辑</span>
        </div>
        <div class="koi-picture-icon" @click="imageViewShow = true">
          <el-icon><ZoomIn /></el-icon>
          <span>查看</span>
        </div>
        <div v-if="!props.disabled" class="koi-picture-icon" @click="handleDeletePicture">
          <el-icon><Delete /></el-icon>
          <span>删除</span>
        </div>
      </div>
    </div>
    <el-image-viewer v-if="imageViewShow" :url-list="[pictureList[0].picturePath]" @close="imageViewShow = false" />
  </div>

  <!-- 选择图片 -->
  <div
    v-if="pictureList.length === 0"
    :style="{ width: props.width, height: props.height, 'border-radius': props.rounded }"
    class="relative border-2px border-dashed border-[--el-color-primary] flex flex-justify-center flex-items-center hover:bg-[--el-color-primary-light-9] m-r-2px m-t-2px"
    @click="handleOpenDialog"
  >
    <div class="koi-upload-image" @click.stop="handleUpload">自定义上传</div>
    <div class="text-[--el-color-primary]">
      <slot name="content">
        <div class="flex flex-col flex-justify-center flex-items-center">
          <el-icon :size="30"><Picture /></el-icon>
          <div class="m-t-8px text-13px text-center">选择图库上传</div>
        </div>
      </slot>
    </div>
  </div>

  <div class="m-t-6px text-12px text-[--el-color-primary] text-align-left">
    <slot name="tip"></slot>
  </div>

  <KoiDialog
    ref="koiImageDialogRef"
    :title="imageTitle"
    :width="1200"
    top="6vh"
    :height="646"
    @koiConfirm="handleConfirm"
    @koiCancel="handleCancel"
  >
    <template #content>
      <div class="koi-flex flex-row">
        <koi-card class="max-w-160px m-r-6px">
          <template #header>
            <div class="flex flex-justify-between select-none">
              <div class="flex flex-items-center gap-6px">
                <el-icon :size="18">
                  <Postcard class="m-b-2px" />
                </el-icon>
                <div>图片分类</div>
              </div>
            </div>
          </template>
          <div
            class="h-26px text-14px text-#555 m-t-2px rounded-6px dark:text-#CFD3DC flex flex-items-center p-y-4px p-x-16px hover:bg-[rgba(0,0,0,0.06)] hover:dark:bg-[rgba(255,255,255,0.06)]"
            v-for="item in koiDicts.sys_picture_type"
            :key="item.dictId"
            :class="selectedIndex === item?.dictValue ? 'bg-[--el-color-primary-light-8]! text-[--el-color-primary]!' : ''"
            @click="handleSelectedIndex(item?.dictValue)"
          >
            <div class="line-clamp-1">{{ item.dictLabel }}</div>
          </div>
        </koi-card>
        <KoiCard>
          <!-- 搜索条件 -->
          <el-form v-show="showSearch" :inline="true">
            <el-form-item label="图片后缀" prop="pictureSuffix">
              <el-input
                placeholder="请输入图片后缀"
                v-model="searchParams.pictureSuffix"
                clearable
                style="width: 220px"
                @keyup.enter.native="handleListPage"
              ></el-input>
            </el-form-item>
            <el-form-item label="服务类型" prop="pictureService">
              <el-select
                placeholder="请选择图片服务类型"
                v-model="searchParams.pictureService"
                clearable
                style="width: 220px"
                @keyup.enter.native="handleListPage"
              >
                <el-option
                  v-for="koi in koiDicts.sys_file_service"
                  :key="koi.dictValue"
                  :label="koi.dictLabel"
                  :value="koi.dictValue"
                />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="search" plain @click="handleSearch" v-auth="['system:picture:search']"
                >搜索</el-button
              >
              <el-button type="danger" icon="refresh" plain @click="resetSearch">重置</el-button>
            </el-form-item>
          </el-form>

          <!-- 表格头部按钮 -->
          <el-row :gutter="10">
            <el-col :span="1.5">
              <el-button type="primary" icon="upload" plain @click="handleUpload()">上传</el-button>
            </el-col>
            <KoiToolbar v-model:showSearch="showSearch" @refreshTable="handleListPage"></KoiToolbar>
          </el-row>

          <div class="h-20px"></div>
          <!-- 图库展示 -->
          <div class="koi-flex flex-row flex-wrap flex-content-start overflow-y-auto">
            <div
              class="pos-relative flex flex-justify-center flex-items-center w-160px h-220px m-y-5px m-r-8px border-rounded border-solid border-1px border-[--el-border-color-light] hover:shadow-[--el-box-shadow-light] bg-[rgba(50,50,50,0.06)] dark:bg-[rgba(255,255,255,0.06)]"
              v-for="item in tableList"
              :key="item.pictureId"
            >
              <el-image
                class="w-100% w-156px h-156px"
                fit="contain"
                :preview-teleported="true"
                :preview-src-list="[item.picturePath]"
                :src="item.picturePath"
              >
                <template #error>
                  <el-image
                    src="https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png"
                    fit="cover"
                    :preview-src-list="['https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png']"
                    :preview-teleported="true"
                    class="w-156px h-156px"
                  ></el-image>
                </template>
              </el-image>
              <!-- 选择图片 -->
              <div class="pos-absolute right-2px top-2px max-w-100px text-16px">
                <el-checkbox
                  size="small"
                  :key="item.pictureId"
                  :value="item.pictureId"
                  v-model="item.checked"
                  label="选择"
                  border
                  @change="handlePictureCheckBox(item)"
                />
              </div>
              <!-- 图片下载/详情/删除 -->
              <div class="pos-absolute right-0 bottom-0 max-w-100px text-16px m-r-4px m-b-2px flex select-none">
                <el-tooltip content="删除文件🌻" placement="top">
                  <div
                    class="m-r-2px hover:text-[--el-color-primary] hover:bg-[rgba(0,0,0,0.06)] rounded hover:dark:bg-[rgba(255,255,255,0.06)]"
                    @click="handleDelete(item)"
                  >
                    <el-icon class="m-4px"><Delete /></el-icon>
                  </div>
                </el-tooltip>

                <el-tooltip placement="top">
                  <template #content>
                    <div class="w-260px text-12px">
                      <div>原名称：{{ item.pictureName }}</div>
                      <div>新名称：{{ item.newName }}</div>
                      <div>文件大小：{{ item.pictureSize }}</div>
                      <div>上传路径：{{ item.pictureUpload }}</div>
                      <div>回显路径：{{ item.picturePath }}</div>
                      <div>
                        服务类型：{{
                          item.pictureService == "1"
                            ? "本地存储"
                            : item.pictureService == "2"
                              ? "MINIO"
                              : item.pictureService == "3"
                                ? "OSS"
                                : "其他"
                        }}
                      </div>
                    </div>
                  </template>
                  <div
                    class="m-r-2px hover:text-[--el-color-primary] hover:bg-[rgba(0,0,0,0.06)] rounded hover:dark:bg-[rgba(255,255,255,0.06)]"
                  >
                    <el-icon class="m-4px"><Warning /></el-icon>
                  </div>
                </el-tooltip>
                <el-tooltip content="下载文件🌻" placement="top">
                  <div
                    class="hover:text-[--el-color-primary] hover:bg-[rgba(0,0,0,0.06)] rounded hover:dark:bg-[rgba(255,255,255,0.06)]"
                    @click="handleDownload(item)"
                  >
                    <el-icon class="m-4px"><Download /></el-icon>
                  </div>
                </el-tooltip>
              </div>
            </div>
          </div>

          <div class="h-20px"></div>
          <!-- 分页 -->
          <el-pagination
            background
            v-model:current-page="searchParams.pageNo"
            v-model:page-size="searchParams.pageSize"
            v-show="total > 0"
            :page-sizes="[10, 20, 50, 100, 200]"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleListPage"
            @current-change="handleListPage"
          />
        </KoiCard>
      </div>
    </template>
  </KoiDialog>

  <KoiDialog
    ref="koiUploadDialogRef"
    title="上传图片🌻"
    :width="360"
    :height="160"
    @koiConfirm="handleUploadConfirm"
    @koiCancel="handleUploadCancel"
  >
    <template #content>
      <KoiUploadImage :width="props.width" :height="props.height" v-model:imageUrl="uploadImageUrl">
        <template #content>
          <el-icon><Picture /></el-icon>
          <span>请上传图片</span>
        </template>
        <template #tip>图片最大为 3M</template>
      </KoiUploadImage>
    </template>
  </KoiDialog>
</template>
<script setup lang="ts">
import { ref, onMounted, computed, defineEmits } from "vue";
import { koiNoticeSuccess, koiNoticeError, koiMsgError, koiMsgWarning, koiMsgBox } from "@/utils/koi.ts";
import { listPage, deleteById } from "@/api/system/picture/index.ts";
import { useKoiDict } from "@/hooks/dicts/index.ts";

interface IPictureProps {
  pictureList?: any[]; // 图库数据，必传值，没有将不显示选择图片
  disabled?: boolean; // 是否禁用
  width?: string;
  height?: string;
  rounded?: string;
}

const props = withDefaults(defineProps<IPictureProps>(), {
  pictureList: () => [],
  disabled: false,
  width: "120px",
  height: "120px",
  rounded: "4px"
});

// 查看图片
const imageViewShow = ref(false);

const emit = defineEmits(["update:pictureList"]);
// 选择图片
const checkedImageList = computed(() => tableList.value.filter((item: any) => item.checked));

/** 选择图片 */
const handlePictureCheckBox = (data: any) => {
  // 单选图片
  if (data.checked && checkedImageList.value.length > 1) {
    data.checked = false;
    koiMsgWarning("最多只能选择一张图片🌻");
    return;
  }
  emit("update:pictureList", checkedImageList.value);
};

/** 编辑图片 */
const handleEditPicture = () => {
  handleOpenDialog();
};

/** 删除图片 */
const handleDeletePicture = () => {
  emit("update:pictureList", []);
};

const imageTitle = ref();
const koiImageDialogRef = ref();

/** 选择图片 */
const handleOpenDialog = () => {
  handleListPage();
  // 标题
  imageTitle.value = "选择图片🌻";
  koiImageDialogRef.value.koiOpen();
  koiNoticeSuccess("选择图库图片🌻");
};

/** 确定  */
const handleConfirm = () => {
  koiImageDialogRef.value.koiQuickClose();
};

/** 取消 */
const handleCancel = () => {
  emit("update:pictureList", []);
  koiImageDialogRef.value.koiClose();
};

const koiUploadDialogRef = ref();
const uploadImageUrl = ref();

/** 自定义上传 */
const handleUpload = () => {
  koiUploadDialogRef.value.koiOpen();
  uploadImageUrl.value = "";
};

/** 确定  */
const handleUploadConfirm = () => {
  emit("update:pictureList", [{ pictureId: new Date().getTime(), picturePath: uploadImageUrl.value }]);
  koiUploadDialogRef.value.koiQuickClose();
};

/** 取消 */
const handleUploadCancel = () => {
  uploadImageUrl.value = "";
  emit("update:pictureList", []);
  koiUploadDialogRef.value.koiClose();
};

const { koiDicts } = useKoiDict(["sys_picture_type", "sys_file_service"]);
// 表格加载动画Loading
const loading = ref(false);
// 是否显示搜索表单[默认显示]
const showSearch = ref<boolean>(true);
// 表格数据
const tableList = ref<any>([]);

// 查询参数
const searchParams = ref<any>({
  pageNo: 1, // 第几页
  pageSize: 10, // 每页显示多少条
  pictureType: "",
  pictureSuffix: "",
  pictureService: ""
});

const total = ref<number>(0);

/** 重置搜索参数 */
const resetSearchParams = () => {
  searchParams.value = {
    pageNo: 1,
    pageSize: 10,
    pictureType: "",
    pictureSuffix: "",
    pictureService: ""
  };
};

/** 搜索 */
const handleSearch = () => {
  searchParams.value.pageNo = 1;
  handleTableData();
};

/** 重置 */
const resetSearch = () => {
  resetSearchParams();
  handleListPage();
};

/** 数据表格 */
const handleListPage = async () => {
  try {
    tableList.value = []; // 重置表格数据
    loading.value = true;
    const res: any = await listPage(searchParams.value);
    if (res.data.records.length > 0) {
      tableList.value = res.data.records.map((item: any) => {
        item.checked = false;
        return item;
      });
    } else {
      tableList.value = res.data.records;
    }
    total.value = res.data.total;
    loading.value = false;
  } catch (error) {
    console.log(error);
    koiNoticeError("数据查询失败，请刷新重试🌻");
  }
};

/** 数据表格[不带Loading，删除、批量删除等使用] */
const handleTableData = async () => {
  try {
    const res: any = await listPage(searchParams.value);
    if (res.data.records.length > 0) {
      tableList.value = res.data.records.map((item: any) => {
        item.checked = false;
        return item;
      });
    } else {
      tableList.value = res.data.records;
    }
    total.value = res.data.total;
  } catch (error) {
    console.log(error);
    koiNoticeError("数据查询失败，请刷新重试🌻");
  }
};

onMounted(() => {
  handleListPage();
});

/** 删除 */
const handleDelete = (row: any) => {
  const id = row.pictureId;
  if (id == null || id == "") {
    koiMsgWarning("请选择需要删除的数据🌻");
    return;
  }
  koiMsgBox("您确认删除该数据么？删除后将无法进行恢复？")
    .then(async () => {
      try {
        await deleteById(id);
        handleTableData();
        koiNoticeSuccess("删除成功🌻");
      } catch (error) {
        console.log(error);
        handleTableData();
        koiNoticeError("删除失败，请刷新重试🌻");
      }
    })
    .catch(() => {
      koiMsgError("已取消🌻");
    });
};

// 选择颜色
const selectedIndex = ref("0");

/** 点击选择分类 */
const handleSelectedIndex = (value?: string) => {
  if (value) {
    selectedIndex.value = value;
    searchParams.value.pictureType = selectedIndex.value;
    handleListPage();
  }
};

/** 文件下载 */
const handleDownload = (row: any) => {
  const fileOriginalName = row?.pictureName;
  const url = row?.picturePath;
  if (url == null || url == "") {
    koiMsgWarning("请选择需要下载的数据🌻");
    return;
  }
  koiMsgBox("您确认下载该数据么？")
    .then(async () => {
      try {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`Network response was not ok: ${response.status}`);
        }
        // 创建 Blob 对象
        const blob = await response.blob();
        // 创建对象 URL
        const downloadUrl = window.URL.createObjectURL(blob);
        // 创建一个隐藏的下载链接
        const link = document.createElement("a");
        link.href = downloadUrl;
        link.download = fileOriginalName; // 设置下载文件名
        link.style.display = "none";
        // 添加到 DOM 中
        document.body.appendChild(link);
        // 触发点击事件
        link.click();
        // 清理
        document.body.removeChild(link);
        window.URL.revokeObjectURL(downloadUrl);
        koiNoticeSuccess("下载成功🌻");
      } catch (error) {
        console.log(error);
        handleTableData();
        koiNoticeError("下载失败，请刷新重试🌻");
      }
    })
    .catch(() => {
      koiMsgError("已取消🌻");
    });
};
</script>

<style lang="scss" scoped>
.koi-pictures-box {
  width: 100%;
  height: 100%;
  position: relative;
  &:hover {
    .koi-picture-operate {
      opacity: 1;
    }
  }
}
.koi-picture {
  width: 120px;
  height: 120px;
  object-fit: contain;
}
.koi-picture-operate {
  position: absolute;
  top: 0;
  right: 0;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  cursor: pointer;
  background: rgb(0 0 0 / 50%);
  border-radius: v-bind(rounded);
  opacity: 0;
  transition: var(--el-transition-duration-fast);
  .koi-picture-icon {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 0 6%;
    color: var(--el-color-primary-light-2);
    .el-icon {
      margin-bottom: 20%;
      font-size: 130%;
      line-height: 130%;
    }
    span {
      text-align: center;
      font-size: 85%;
      line-height: 110%;
    }
  }
}
.koi-upload-image {
  position: absolute;
  top: 0;
  border: 1px dashed var(--el-color-primary);
  border-top: 1px dashed transparent;
  width: 100%;
  height: 30px;
  line-height: 30px;
  border-radius: 6px 6px 20px 20px;
  text-align: center;
  font-size: 12px;
  color: var(--el-color-primary);
}
</style>
